import json
from typing import Dict, Any, Optional, AsyncGenerator

from autogen_agentchat.messages import TextMessage
from autogen_core import CancellationToken

from agent.OpenaiAssistantAgent import OpenaiAssistantAgent
from config.yaml_settings import get_llm_model_config, get_llm_api_config, LLMModelConfig, LLMAPIConfig
from mcp_tools.SqlTools import get_sql_tools


class ReportAnalysisWorkflow:
    """报表分析工作流协调器 - LLM分析意图，生成SQL，执行查询，生成图表"""

    def __init__(self,
                 api_key: Optional[str] = None,
                 base_url: Optional[str] = None,
                 model_config: Optional[LLMModelConfig] = None,
                 api_config: Optional[LLMAPIConfig] = None):
        # 使用传入的配置或默认配置
        if api_config is None:
            api_config = get_llm_api_config()
        if model_config is None:
            model_config = get_llm_model_config()

        self.api_key = api_key or api_config.api_key
        self.base_url = base_url or api_config.base_url
        self.model_config = model_config
        self.api_config = api_config
        self.analysis_agent = None
        self.chart_agent = None
        self.sql_tools = None
        self._initialized = False

    async def initialize(self):
        """初始化工作流组件"""
        if self._initialized:
            return

        try:
            # 初始化SQL工具
            self.sql_tools = await get_sql_tools()

            # 使用现有的OpenaiAssistantAgent创建分析Agent
            self.analysis_agent = OpenaiAssistantAgent(
                name="report_analysis_agent",
                api_key=self.api_key,
                base_url=self.base_url,
                system_message=self._get_analysis_system_message(),
                model_config=self.model_config,
                api_config=self.api_config
            )

            # 使用现有的OpenaiAssistantAgent创建图表Agent
            self.chart_agent = OpenaiAssistantAgent(
                name="chart_generation_agent",
                api_key=self.api_key,
                base_url=self.base_url,
                system_message=self._get_chart_system_message(),
                model_config=self.model_config,
                api_config=self.api_config
            )

            self._initialized = True
            print("报表分析工作流初始化完成")

        except Exception as e:
            print(f"工作流初始化失败: {str(e)}")
            raise

    def _get_analysis_system_message(self) -> str:
        """获取分析Agent的系统消息 - LLM分析意图并生成SQL"""
        return """你是一个专业的报表分析专家。你的任务是：

1. 理解用户的报表分析需求
2. 分析数据库表结构信息
3. 根据用户需求和表结构生成合适的SQL查询
4. 将查询结果传递给图表生成Agent生成ECharts图表

工作流程：
1. 分析用户需求，确定需要查询的数据类型和范围
2. 查看数据库表结构，了解可用的表和字段
3. 根据用户需求和表结构生成SQL查询语句
4. 执行SQL查询获取数据
5. 将数据传递给图表Agent生成图表

重要规则：
- 生成的SQL必须基于实际存在的表结构
- 只能使用实际存在的表和字段
- 如果用户需求涉及的表不存在，请明确说明并建议可用的替代表
- 生成的SQL必须符合MySQL语法规范
- 支持各种类型的报表分析，包括但不限于财务、销售、用户、产品等数据

请严格按照这个流程执行，确保每个步骤都正确完成。"""

    def _get_chart_system_message(self) -> str:
        """获取图表Agent的系统消息 - 生成完整HTML代码"""
        return """你是一个专业的数据可视化专家。你的任务是根据提供的数据和需求，生成完整的HTML代码，包含1-3种不同维度的ECharts图表。

CRITICAL RULES - 必须严格遵守：
1. 返回完整的HTML代码，包含<html>, <head>, <body>等标签
2. 包含ECharts CDN引用
3. 根据数据特点生成1-3种不同维度的图表：
   - 如果用户没有限制图表类型，可以生成多种图表展示不同维度
   - 趋势分析：折线图
   - 对比分析：柱状图 
   - 占比分析：饼图
   - 分布分析：散点图
   - 多维度分析：雷达图
4. 所有JavaScript代码必须在HTML中完整可执行
5. 使用现代化的深色主题样式
6. 确保图表响应式布局
7. 使用Tailwind CSS CDN进行样式设计
8. 确保所有图表都能正常显示，避免JavaScript错误
9. 在ECharts配置中不要使用JavaScript函数，只使用字符串和数字

HTML模板结构：
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据分析报告</title>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        dark: {
                            50: '#f8fafc',
                            100: '#f1f5f9',
                            200: '#e2e8f0',
                            300: '#cbd5e1',
                            400: '#94a3b8',
                            500: '#64748b',
                            600: '#475569',
                            700: '#334155',
                            800: '#1e293b',
                            900: '#0f172a',
                            950: '#020617'
                        }
                    }
                }
            }
        }
    </script>
    <style>
        body {
            background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
            min-height: 100vh;
        }
    </style>
</head>
<body class="bg-dark-900 text-gray-100">
    <div class="container mx-auto px-4 py-8 max-w-7xl">
        <div class="bg-dark-800 rounded-2xl shadow-2xl p-8">
            <!-- 标题区域 -->
            <div class="text-center mb-8 pb-6 border-b border-dark-600">
                <h1 class="text-4xl font-light text-gray-100 mb-3">数据分析报告</h1>
                <p class="text-gray-400 text-lg">基于智能分析的可视化数据报告</p>
            </div>
            
            <!-- 图表容器 -->
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-8">
                <div class="bg-dark-700 rounded-xl p-6 border border-dark-600">
                    <h3 class="text-xl font-medium text-gray-100 mb-4 text-center">图表标题1</h3>
                    <div id="chart1" class="w-full h-96 rounded-lg"></div>
                </div>
                <div class="bg-dark-700 rounded-xl p-6 border border-dark-600">
                    <h3 class="text-xl font-medium text-gray-100 mb-4 text-center">图表标题2</h3>
                    <div id="chart2" class="w-full h-96 rounded-lg"></div>
                </div>
            </div>
            
            <!-- 总结区域 -->
            <div class="bg-dark-700 rounded-xl p-6 border border-dark-600">
                <h3 class="text-xl font-medium text-gray-100 mb-4">分析总结</h3>
                <p class="text-gray-300 leading-relaxed">根据数据分析结果，这里是对数据的总结和洞察...</p>
            </div>
        </div>
    </div>
    
    <script>
        // 等待页面加载完成
        document.addEventListener('DOMContentLoaded', function() {
            // 初始化图表
            initCharts();
        });
        
        function initCharts() {
            // 图表初始化代码
            // 确保在DOM加载完成后执行
            console.log('图表初始化开始...');
            
            // 示例：初始化第一个图表
            const chart1 = document.getElementById('chart1');
            if (chart1) {
                const myChart1 = echarts.init(chart1);
                const option1 = {
                    title: {
                        text: '示例图表1',
                        textStyle: {
                            color: '#e5e7eb'
                        }
                    },
                    tooltip: {
                        trigger: 'axis'
                    },
                    xAxis: {
                        type: 'category',
                        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
                        axisLabel: {
                            color: '#9ca3af'
                        }
                    },
                    yAxis: {
                        type: 'value',
                        axisLabel: {
                            color: '#9ca3af'
                        }
                    },
                    series: [{
                        data: [820, 932, 901, 934, 1290, 1330, 1320],
                        type: 'line',
                        smooth: true
                    }]
                };
                myChart1.setOption(option1);
            }
            
            // 示例：初始化第二个图表
            const chart2 = document.getElementById('chart2');
            if (chart2) {
                const myChart2 = echarts.init(chart2);
                const option2 = {
                    title: {
                        text: '示例图表2',
                        textStyle: {
                            color: '#e5e7eb'
                        }
                    },
                    tooltip: {
                        trigger: 'item'
                    },
                    series: [{
                        name: '访问来源',
                        type: 'pie',
                        radius: '50%',
                        data: [
                            {value: 1048, name: '搜索引擎'},
                            {value: 735, name: '直接访问'},
                            {value: 580, name: '邮件营销'},
                            {value: 484, name: '联盟广告'},
                            {value: 300, name: '视频广告'}
                        ],
                        emphasis: {
                            itemStyle: {
                                shadowBlur: 10,
                                shadowOffsetX: 0,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        }
                    }]
                };
                myChart2.setOption(option2);
            }
        }
        
        // 响应式处理
        window.addEventListener('resize', function() {
            const charts = document.querySelectorAll('[id^="chart"]');
            charts.forEach(chart => {
                const instance = echarts.getInstanceByDom(chart);
                if (instance) {
                    instance.resize();
                }
            });
        });
    </script>
</body>
</html>
```

请返回完整的HTML代码，可以直接在浏览器中渲染。确保：
1. 使用Tailwind CSS CDN进行样式设计
2. 确保所有图表都能正常显示
3. 添加适当的错误处理
4. 使用响应式布局
5. 在ECharts配置中只使用字符串和数字，不要使用JavaScript函数"""

    async def analyze_report_data(self, user_query: str) -> Dict[str, Any]:
        """执行报表数据分析工作流 - 非流式版本（保持兼容性）"""
        if not self._initialized:
            await self.initialize()

        cancellation_token = CancellationToken()

        try:
            print(f"开始处理用户查询: {user_query}")

            # 步骤1: 获取数据库表结构信息
            print("步骤1: 获取数据库表结构...")
            table_info_result = await self.sql_tools.get_all_tables(cancellation_token)
            print(table_info_result)
            if table_info_result.get("status") == "error":
                return {
                    "status": "error",
                    "user_query": user_query,
                    "error": table_info_result.get("error", "获取表结构失败")
                }
            table_info = table_info_result.get("data", "")
            print(f"表结构信息: {table_info}")

            # 步骤2: LLM分析用户意图并生成SQL
            print("步骤2: LLM分析用户意图并生成SQL...")
            sql_query = await self._generate_sql_query(user_query, table_info, cancellation_token)
            if sql_query.startswith("SQL生成失败"):
                return {
                    "status": "error",
                    "user_query": user_query,
                    "error": sql_query
                }
            print(f"生成的SQL: {sql_query}")

            # 步骤3: 执行SQL查询
            print("步骤3: 执行SQL查询...")
            query_result = await self.sql_tools.execute_custom_sql(sql_query, cancellation_token)
            if query_result.get("status") == "error":
                return {
                    "status": "error",
                    "user_query": user_query,
                    "error": query_result.get("error", "SQL执行失败")
                }
            print(f"查询结果: {query_result}")

            # 步骤4: 生成HTML报告
            print("步骤4: 生成HTML报告...")
            html_report = await self._generate_html_report(query_result, user_query, cancellation_token)
            if html_report.startswith("HTML生成失败"):
                return {
                    "status": "error",
                    "user_query": user_query,
                    "error": html_report
                }

            # 步骤5: 返回结果
            result = {
                "status": "success",
                "user_query": user_query,
                "sql_query": sql_query,
                "data": query_result.get("data", ""),
                "html_report": html_report
            }

            print("报表分析工作流执行完成")
            return result

        except Exception as e:
            error_result = {
                "status": "error",
                "user_query": user_query,
                "error": str(e)
            }
            print(f"工作流执行失败: {str(e)}")
            return error_result

    async def analyze_report_data_stream(self, user_query: str) -> AsyncGenerator[Dict[str, Any], None]:
        """执行报表数据分析工作流 - 流式版本"""
        if not self._initialized:
            await self.initialize()

        cancellation_token = CancellationToken()

        try:
            print(f"开始处理用户查询: {user_query}")

            # 发送开始信号
            yield {
                "step": "start",
                "status": "processing",
                "message": "开始分析用户查询...",
                "user_query": user_query
            }

            # 步骤1: 获取数据库表结构信息
            print("步骤1: 获取数据库表结构...")
            yield {
                "step": "table_info",
                "status": "processing",
                "message": "正在获取数据库表结构信息..."
            }

            table_info_result = await self.sql_tools.get_all_tables(cancellation_token)
            if table_info_result.get("status") == "error":
                yield {
                    "step": "table_info",
                    "status": "error",
                    "error": table_info_result.get("error", "获取表结构失败")
                }
                return

            table_info = table_info_result.get("data", "")
            yield {
                "step": "table_info",
                "status": "success",
                "message": "数据库表结构获取成功",
                "data": table_info
            }

            # 步骤2: LLM分析用户需求并确定相关表
            print("步骤2: LLM分析用户需求并确定相关表...")
            yield {
                "step": "table_selection",
                "status": "processing",
                "message": "正在分析用户需求并确定相关表..."
            }

            selected_tables = await self._select_relevant_tables(user_query, table_info, cancellation_token)
            if selected_tables.startswith("表选择失败"):
                yield {
                    "step": "table_selection",
                    "status": "error",
                    "error": selected_tables
                }
                return

            yield {
                "step": "table_selection",
                "status": "success",
                "message": "相关表确定成功",
                "selected_tables": selected_tables
            }

            # 步骤3: 获取选定表的详细字段信息
            print("步骤3: 获取选定表的详细字段信息...")
            yield {
                "step": "field_info",
                "status": "processing",
                "message": "正在获取选定表的详细字段信息..."
            }

            field_info = await self._get_table_fields_info(selected_tables, cancellation_token)
            if field_info.startswith("字段信息获取失败"):
                yield {
                    "step": "field_info",
                    "status": "error",
                    "error": field_info
                }
                return

            yield {
                "step": "field_info",
                "status": "success",
                "message": "字段信息获取成功",
                "field_info": field_info
            }

            # 步骤4: LLM根据字段信息生成SQL
            print("步骤4: LLM根据字段信息生成SQL...")
            yield {
                "step": "sql_generation",
                "status": "processing",
                "message": "正在根据字段信息生成SQL查询..."
            }

            sql_query = await self._generate_sql_with_fields(user_query, field_info, cancellation_token)
            if sql_query.startswith("SQL生成失败"):
                yield {
                    "step": "sql_generation",
                    "status": "error",
                    "error": sql_query
                }
                return

            yield {
                "step": "sql_generation",
                "status": "success",
                "message": "SQL查询生成成功",
                "sql_query": sql_query
            }

            # 步骤5: 执行SQL查询
            print("步骤5: 执行SQL查询...")
            yield {
                "step": "sql_execution",
                "status": "processing",
                "message": "正在执行SQL查询..."
            }

            query_result = await self.sql_tools.execute_custom_sql(sql_query, cancellation_token)
            if query_result.get("status") == "error":
                yield {
                    "step": "sql_execution",
                    "status": "error",
                    "error": query_result.get("error", "SQL执行失败")
                }
                return

            yield {
                "step": "sql_execution",
                "status": "success",
                "message": "SQL查询执行成功",
                "data": query_result.get("data", "")
            }

            # 步骤6: 生成HTML报告
            print("步骤6: 生成HTML报告...")
            yield {
                "step": "html_generation",
                "status": "processing",
                "message": "正在生成HTML可视化报告..."
            }

            html_report = await self._generate_html_report(query_result, user_query, cancellation_token)
            if html_report.startswith("HTML生成失败"):
                yield {
                    "step": "html_generation",
                    "status": "error",
                    "error": html_report
                }
                return

            yield {
                "step": "html_generation",
                "status": "success",
                "message": "HTML报告生成成功",
                "html_report": html_report
            }

            # 完成信号
            yield {
                "step": "complete",
                "status": "success",
                "message": "报表分析工作流执行完成",
                "user_query": user_query,
                "sql_query": sql_query,
                "data": query_result.get("data", ""),
                "html_report": html_report
            }

        except Exception as e:
            yield {
                "step": "error",
                "status": "error",
                "error": str(e),
                "message": f"工作流执行失败: {str(e)}"
            }

    async def _generate_sql_query(self, user_query: str, table_info: str, cancellation_token: CancellationToken) -> str:
        """LLM生成SQL查询"""
        try:
            prompt = f"""
用户需求: {user_query}

数据库表结构信息:
{table_info}

请根据用户需求和表结构信息生成合适的SQL查询语句。

重要规则：
1. 只能使用实际存在的表，不能创建或假设不存在的表
2. 生成的SQL必须基于实际查询到的表结构
3. 如果用户需求涉及的表不存在，请明确说明并建议可用的替代表
4. 生成的SQL必须符合MySQL语法规范
5. 如果找不到合适的表，请返回"未找到合适的表"并说明原因
6. 只返回纯SQL语句，不要包含任何其他文字或说明

请生成合适的SQL查询语句来获取相关数据。只返回SQL语句，不要其他说明。
"""
            response = await self.analysis_agent.on_messages(
                [TextMessage(content=prompt, source="workflow")],
                cancellation_token
            )
            return response.chat_message.content.strip()
        except Exception as e:
            return f"SQL生成失败: {str(e)}"

    async def _select_relevant_tables(self, user_query: str, table_info: str,
                                      cancellation_token: CancellationToken) -> str:
        """LLM分析用户需求并选择相关表"""
        try:
            prompt = f"""
用户需求: {user_query}

数据库中的所有表:
{table_info}

请分析用户需求，从上述表中选择与用户需求相关的表。

选择规则：
1. 仔细分析用户需求，确定需要查询的数据类型
2. 从表名和注释中判断表的用途
3. 选择与用户需求最相关的1-3个表
4. 如果找不到相关表，请明确说明

请返回选择的表名，用逗号分隔，例如：sys_log, sys_user
只返回表名，不要其他说明。
"""
            print(f"[表选择] 发送请求到LLM...")
            print(f"[表选择] 请求内容: {prompt[:200]}...")

            response = await self.analysis_agent.on_messages(
                [TextMessage(content=prompt, source="workflow")],
                cancellation_token
            )

            result = response.chat_message.content.strip()
            print(f"[表选择] LLM响应: {result}")
            return result
        except Exception as e:
            error_msg = f"表选择失败: {str(e)}"
            print(f"[表选择] 错误: {error_msg}")
            return error_msg

    async def _get_table_fields_info(self, selected_tables: str, cancellation_token: CancellationToken) -> str:
        """获取选定表的详细字段信息"""
        try:
            print(f"[字段信息] 开始获取表字段信息...")
            print(f"[字段信息] 选定的表: {selected_tables}")

            table_names = [table.strip() for table in selected_tables.split(',')]
            field_info_list = []

            for table_name in table_names:
                if table_name:
                    print(f"[字段信息] 获取表 {table_name} 的结构...")
                    # 获取表结构
                    structure_result = await self.sql_tools.get_table_structure(table_name, cancellation_token)
                    print(f"[字段信息] 表 {table_name} 结构查询结果: {structure_result}")

                    if structure_result.get("status") == "success":
                        field_info_list.append(f"表名: {table_name}")
                        field_info_list.append(f"字段信息: {structure_result.get('data', '')}")
                        field_info_list.append("---")
                    else:
                        print(f"[字段信息] 表 {table_name} 结构获取失败: {structure_result.get('error', '未知错误')}")

            result = "\n".join(field_info_list)
            print(f"[字段信息] 最终字段信息: {result[:200]}...")
            return result
        except Exception as e:
            error_msg = f"字段信息获取失败: {str(e)}"
            print(f"[字段信息] 错误: {error_msg}")
            return error_msg

    async def _generate_sql_with_fields(self, user_query: str, field_info: str,
                                        cancellation_token: CancellationToken) -> str:
        """根据字段信息生成SQL查询"""
        try:
            prompt = f"""
用户需求: {user_query}

相关表的字段信息:
{field_info}

请根据用户需求和上述字段信息生成准确的SQL查询语句。

重要规则：
1. 只能使用上述字段信息中存在的字段
2. 生成的SQL必须基于实际存在的表和字段
3. 生成的SQL必须符合MySQL语法规范
4. 如果用户需求涉及不存在的字段，请使用最接近的替代字段
5. 只返回纯SQL语句，不要包含任何其他文字或说明

请生成合适的SQL查询语句来获取相关数据。只返回SQL语句，不要其他说明。
"""
            print(f"[SQL生成] 发送请求到LLM...")
            print(f"[SQL生成] 请求内容: {prompt[:200]}...")

            response = await self.analysis_agent.on_messages(
                [TextMessage(content=prompt, source="workflow")],
                cancellation_token
            )

            result = response.chat_message.content.strip()
            print(f"[SQL生成] LLM响应: {result}")
            return result
        except Exception as e:
            error_msg = f"SQL生成失败: {str(e)}"
            print(f"[SQL生成] 错误: {error_msg}")
            return error_msg

    async def _generate_html_report(self, query_result: Dict[str, Any], user_query: str,
                                    cancellation_token: CancellationToken) -> str:
        """生成完整的HTML报告"""
        try:
            # 提取查询结果数据
            data = query_result.get("data", [])
            if not data:
                return "HTML生成失败: 查询结果为空"
            
            # 确保数据是列表格式
            if isinstance(data, str):
                try:
                    # 尝试解析字符串为JSON
                    data = json.loads(data)
                except:
                    # 如果解析失败，尝试使用eval (仅用于开发环境)
                    try:
                        data = eval(data)
                    except:
                        pass
            
            # 如果数据不是列表，转换为列表
            if not isinstance(data, list):
                data = [data]
            
            # 分析数据结构，提取列名和数据类型
            columns = []
            data_types = {}
            
            if data and isinstance(data[0], dict):
                # 从第一条记录中提取列名
                columns = list(data[0].keys())
                
                # 分析每列的数据类型
                for col in columns:
                    # 初始化该列的数据类型
                    data_types[col] = "string"  # 默认为字符串类型
                    
                    # 检查前10条记录（或全部记录，如果少于10条）来确定数据类型
                    sample_size = min(10, len(data))
                    numeric_count = 0
                    date_count = 0
                    
                    for i in range(sample_size):
                        if i < len(data) and col in data[i]:
                            value = data[i][col]
                            
                            # 检查是否为数值类型
                            if isinstance(value, (int, float)) or (
                                    isinstance(value, str) and value.replace('.', '', 1).isdigit()):
                                numeric_count += 1
                            
                            # 检查是否可能是日期类型（简单检查）
                            if isinstance(value, str) and (
                                    '-' in value or '/' in value) and (
                                    len(value) >= 8 and len(value) <= 30):
                                date_count += 1
                    
                    # 根据样本判断类型
                    if numeric_count >= sample_size * 0.7:  # 如果70%以上是数值
                        data_types[col] = "numeric"
                    elif date_count >= sample_size * 0.7:  # 如果70%以上可能是日期
                        data_types[col] = "date"
            
            # 准备提示词，只包含数据格式而不是全量数据
            try:
                # 尝试将数据样例转换为JSON字符串
                sample_data_json = json.dumps(data[:3], ensure_ascii=False, indent=2)
            except TypeError:
                # 如果转换失败，尝试手动构建样例数据字符串
                sample_data = []
                for i, item in enumerate(data[:3]):
                    if i >= 3:  # 只取前3条
                        break
                    try:
                        # 尝试将每个项目转换为字典
                        if isinstance(item, dict):
                            sample_item = {}
                            for k, v in item.items():
                                # 确保值是可序列化的
                                if isinstance(v, (str, int, float, bool, type(None))):
                                    sample_item[k] = v
                                else:
                                    sample_item[k] = str(v)
                            sample_data.append(sample_item)
                        else:
                            # 如果不是字典，转换为字符串
                            sample_data.append(str(item))
                    except:
                        # 如果处理失败，添加一个占位符
                        sample_data.append(f"[复杂数据项 {i+1}]")
                
                # 手动构建JSON格式的字符串
                sample_data_json = str(sample_data)
            
            prompt = f"""
用户查询: {user_query}

数据结构信息:
- 总记录数: {len(data)}
- 列名: {columns}
- 数据类型: {data_types}

数据样例（前3条记录）:
{sample_data_json}

请根据以上数据结构和用户查询，生成一个包含1-3个ECharts图表的完整HTML报告。
图表类型应根据数据特点选择合适的类型（折线图、柱状图、饼图等）。
请确保生成的HTML代码完整可执行，包含所有必要的CSS和JavaScript。
"""
            
            # 调用LLM生成HTML报告
            print(f"[HTML生成] 发送请求到LLM...")
            print(f"[HTML生成] 请求内容: {prompt[:200]}...")
            
            response = await self.chart_agent.on_messages(
                [TextMessage(content=prompt, source="workflow")],
                cancellation_token
            )
            
            html_report = response.chat_message.content.strip()
            print(f"[HTML生成] HTML报告生成成功，长度: {len(html_report)}")
            
            # 清理可能的Markdown代码块标记
            if html_report.startswith("```html"):
                html_report = html_report.replace("```html", "", 1)
                if html_report.endswith("```"):
                    html_report = html_report[:-3]
            
            # 清理其他可能的Markdown标记
            html_report = html_report.strip()
            
            return html_report
        except Exception as e:
            error_msg = f"HTML生成失败: {str(e)}"
            print(f"[HTML生成] 错误: {error_msg}")
            return error_msg


    async def get_workflow_status(self) -> Dict[str, Any]:
        """获取工作流状态"""
        if not self._initialized:
            await self.initialize()
        
        return {
            "status": "ready" if self._initialized else "not_initialized",
            "available_tools": ["get_all_tables", "get_table_structure", "execute_custom_sql"],
            "message": "工作流已初始化" if self._initialized else "工作流未初始化"
        }


# 全局工作流实例
_workflow_instance = None

async def get_workflow(api_key: str = None, base_url: str = None):
    """获取工作流实例（单例模式）"""
    global _workflow_instance
    
    if _workflow_instance is None:
        _workflow_instance = ReportAnalysisWorkflow(api_key=api_key, base_url=base_url)
        await _workflow_instance.initialize()
    
    return _workflow_instance
